﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Reflection;
using exsportance.Silverlight.Common.Utils;

namespace exsportance.Silverlight.Validate.Validators
{
    public abstract class BaseValidator : IValidator
    {
        #region members
        private List<string> _messages;
        private object _value;
        protected Dictionary<string, string> _messageVariables;
        protected bool _allowMessages = true;
        #endregion

        #region properties
        public List<string> Messages
        {
            get { return _messages; }
        }

        public Dictionary<string, string> MessagesVariables
        {
            get { return _messageVariables; }
        }
        #endregion

        #region constructor
        public BaseValidator()
        {
            _messages = new List<string>();
            _messageVariables = new Dictionary<string, string>();
        }
        #endregion

        #region public methods
        /// <summary>
        /// Main method to check validation, with messages
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Validate(object value, bool allowMessages)
        {
            bool result = false;

            // clear old messages
            _messages.Clear();

            // enable messages
            _allowMessages = allowMessages;

            result = CheckValid(value);

            return result;
        }

        protected abstract bool CheckValid(object value);


        #endregion

        #region protected methods
        protected abstract Dictionary<string, string> getMessageTemplates();

        protected void rememberValue(object value)
        {
            _value = value;
        }

        protected void addMessage(string message)
        {
            if (_allowMessages)
                _messages.Add(message);
        }

        protected void raiseMessage(string messageConst)
        {
            if (!_allowMessages)
                return;

            string message = messageConst;

            Dictionary<string, string> messages = getMessageTemplates();
            if (messages != null)
            {
                if (!messages.ContainsKey(messageConst))
                    throw new Exception("Message key '{0}' does not exists!".Frmt(messageConst));

                message = messages[messageConst];

                string value = _value == null ? "" : _value.ToString();

                message = message.Replace("%value%", value);

                foreach (KeyValuePair<string, string> item in _messageVariables)
                    message = message.Replace("%{0}%".Frmt(item.Key), item.Value);

                // use properties as message variables
                PropertyInfo[] infos = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (PropertyInfo propertyInfo in infos)
                {
                    int index = message.IndexOf("%{0}%".Frmt(propertyInfo.Name), StringComparison.InvariantCultureIgnoreCase);
                    if (index > -1)
                    {
                        object propertyValue = propertyInfo.GetValue(this, null);
                        message = message.Remove(index, propertyInfo.Name.Length + 2).Insert(index, propertyValue.ToString());
                    }
                }
            }

            addMessage(message);
        }
        #endregion
    }
}
